package com.qkhero.api.builder;

import com.qkhero.api.exception.RequestBuilderNotFoundException;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by zhengwei on 2017/4/16.
 */
@Component
public class DefaultRequestBuilderResolver implements RequestBuilderResolver, InitializingBean, ApplicationContextAware {

    private final static Logger LOGGER = LoggerFactory.getLogger(DefaultRequestBuilderResolver.class);

    private ApplicationContext applicationContext;

    /**
     * key=apiName
     */
    private Map<String, RequestBuilder> requestBuilders;

    @Override
    public RequestBuilder resolve(String apiName) throws RequestBuilderNotFoundException {

        RequestBuilder requestBuilder = requestBuilders.get(apiName);
        if (requestBuilder == null) {
            throw new RequestBuilderNotFoundException("can not find RequestBuilder apiName='" + apiName + "'");
        }

        return requestBuilder;
    }

    @Override
    public void afterPropertiesSet() throws Exception {

        Map<String, RequestBuilder> builderMap = this.applicationContext.getBeansOfType(RequestBuilder.class);

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("find {} RequestBuilders", builderMap != null ? builderMap.size() : 0);
        }

        if (MapUtils.isNotEmpty(builderMap)) {

            Map<String, RequestBuilder> requestBuilders = new HashMap<>(builderMap.size());

            for (Map.Entry<String, RequestBuilder> builderEntry : builderMap.entrySet()) {

                requestBuilders.put(builderEntry.getValue().supportApiName(), builderEntry.getValue());
            }

            this.requestBuilders = requestBuilders;
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
